﻿using System.Globalization;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace netTool.util;

/// <summary>
/// 
/// </summary>
public static class StringExp {

    // 预计算十六进制字符值表（ASCII优化版）
    private static readonly byte[] HexValues = new byte[256];

    /// <summary>
    /// 
    /// </summary>
    static StringExp() {
        for (int i = 0; i < 256; i++) {
            char c = (char)i;
            HexValues[i] = (byte)(
                (c >= '0' && c <= '9') ? c - '0' :
                (c >= 'A' && c <= 'F') ? c - 'A' + 10 :
                (c >= 'a' && c <= 'f') ? c - 'a' + 10 :
                255 // 非法字符标记
            );
        }
    }


    /// <summary>
    /// 当前字符串不是空，IsNotNullOrWhiteSpace为假
    /// </summary>
    /// <param name="orgString"></param>
    /// <returns></returns>
    public static bool IsNullOrWhiteSpace(this string orgString) {
        return string.IsNullOrWhiteSpace(orgString);
    }

    /// <summary>
    /// 当前字符串不是空，IsNotNullOrWhiteSpace为假
    /// </summary>
    /// <param name="orgString"></param>
    /// <returns></returns>
    public static bool IsNotNullOrWhiteSpace(this string orgString) {
        return !string.IsNullOrWhiteSpace(orgString);
    }

    /// <summary>
    ///字符串转换为字节，只处理数字串最左边2个数字，长度小于2返回0x00
    /// 如 1234 转换为{ 0x12 }
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static byte BcdToByte(this string str) {
        byte bOut = new byte();
        if (str.IsNullOrWhiteSpace()) return bOut;
        if (str.Length < 2) return bOut;

        byte[] bGroup = new byte[str.Length / 2];
        int index = 0;
        for (int i = 0; i < bGroup.Length; i++) {
            bGroup[i] = Convert.ToByte(int.Parse(str.Substring(index, 2), NumberStyles.HexNumber));
            index = index + 2;
        }
        return bGroup[0];
    }

    /// <summary>
    ///字符串转换为数组
    /// 如 1234 转换为{ 0x12, 0x34 }
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static byte[] BcdToBytes(this string str) {
        byte[] bGroup = new byte[str.Length / 2];
        int index = 0;
        for (int i = 0; i < bGroup.Length; i++) {
            bGroup[i] = Convert.ToByte(int.Parse(str.Substring(index, 2), NumberStyles.HexNumber));
            index = index + 2;
        }
        return bGroup;
    }

    /// <summary>
    /// 字符串反转
    /// </summary>
    /// <param name="oldStr"></param>
    /// <returns></returns>
    public static string Reverse(this string oldStr) {
        StringBuilder newStr = new StringBuilder();
        Stack<char> strStack = new Stack<char>();
        foreach (char c in oldStr) {
            strStack.Push(c);
        }
        while (strStack.Count > 0) {
            newStr.Append(strStack.Pop());
        }
        return newStr.ToString();
    }

    #region 转换

    /// <summary>
    /// 二进制字符串转换为byte，字符串为空或者NULL时返回0
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static byte SecStringToByte(this string str) {
        if (string.IsNullOrWhiteSpace(str))
            return 0;

        if (str == "&nbsp;")
            return 0;

        return Convert.ToByte(str, 2);
    }

    /// <summary>
    /// 10进制字符串转换为byte，字符串为空或者NULL时返回0 ，如"100"->0x64
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static byte ToByte(this string str) {
        if (string.IsNullOrWhiteSpace(str))
            return 0;
        if (str == "&nbsp;")
            return 0;
        return Convert.ToByte(str);
    }

    /// <summary>
    /// 字符串(允许有空格)转换为数组
    /// 如 "12 34" 转换为{ 0x12, 0x34 }
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static byte[] ToBytes(this string str) {
        if (string.IsNullOrEmpty(str))
            return [];

        // 预处理阶段（单次遍历）
        int validLength = 0;
        bool hasInvalidChar = false;
        Span<char> buffer = stackalloc char[str.Length];

        foreach (char c in str) {
            if (char.IsWhiteSpace(c)) continue;
            if (c > 255 || HexValues[c] == 255) {
                hasInvalidChar = true;
                break;
            }
            buffer[validLength++] = c;
        }

        if (hasInvalidChar)
            throw new FormatException("包含非法的十六进制字符");

        if (validLength == 0)
            return [];

        if ((validLength & 1) != 0)
            throw new FormatException("十六进制字符串长度必须为偶数");

        // 转换阶段（无堆分配）
        int byteCount = validLength / 2;
        byte[] result = new byte[byteCount];

        for (int i = 0; i < byteCount; i++) {
            int high = HexValues[buffer[i * 2]];
            int low = HexValues[buffer[i * 2 + 1]];
            result[i] = (byte)((high << 4) | low);
        }

        return result;
    }

    ///  <summary>
    ///  字符串转换为数组,不足时左补0
    ///  如 "1234" 转换为{ 0x12, 0x34 }
    ///  </summary>
    ///  <param name="str"></param>
    /// <param name="length"></param>
    /// <param name="paddingChar"></param>
    /// <returns></returns>
    public static byte[] PadLeftBytes(this string str, int length, char paddingChar = '0') {
        byte[] bGroup = new byte[length / 2];
        int index = 0;
        for (int i = 0; i < bGroup.Length; i++) {
            bGroup[i] = Convert.ToByte(int.Parse(str.PadLeft(length, '0').Substring(index, 2), NumberStyles.HexNumber));
            index = index + 2;
        }
        return bGroup;
    }

    /// <summary>
    /// 10进制字符串转换为byte，字符串为空或者NULL时返回0 ，如"100"->0x64
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static byte TryToByte(this string str) {
        try {
            return ToByte(str);
        }
        catch (Exception) {
            return 0;
        }
    }


    /// <summary>
    /// 10进制字符串转换为byte，字符串为空或者NULL时返回0 ，如"100"->0x64
    /// </summary>
    /// <param name="str"></param>
    /// <param name="outValue"></param>
    /// <returns></returns>
    public static bool TryToByte(this string str, out int outValue) {
        outValue = 0;
        try {
            outValue = ToByte(str);
            return true;
        }
        catch (Exception) {
            return false;
        }
    }

    /// <summary>
    /// 10进制字符串转换为Int32，字符串为空或者NULL时返回0 ，如"100"->0x64
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static int ToInt(this string str) {
        if (string.IsNullOrWhiteSpace(str))
            return 0;
        if (str == "&nbsp;")
            return 0;
        return Convert.ToInt32(str);
    }

    /// <summary>
    /// 字符串转换为Int32，字符串为空或者NULL时返回0
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static int TryToInt(this string str) {
        try {
            return ToInt(str);
        }
        catch (Exception) {
            return 0;
        }
    }

    /// <summary>
    /// 字符串转换为Int32，字符串为空或者NULL时返回0
    /// </summary>
    /// <param name="str"></param>
    /// <param name="outValue"></param>
    /// <returns></returns>
    public static bool TryToInt(this string str, out int outValue) {
        outValue = 0;
        try {
            outValue = ToInt(str);
            return true;
        }
        catch (Exception) {
            return false;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static Int16 ToInt16(this string str) {
        if (string.IsNullOrWhiteSpace(str))
            return 0;
        if (str == "&nbsp;")
            return 0;
        return Convert.ToInt16(str);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static UInt16 ToUInt16(this string str) {
        if (string.IsNullOrWhiteSpace(str))
            return 0;
        if (str == "&nbsp;")
            return 0;
        return Convert.ToUInt16(str);
    }

    /// <summary>
    /// 字符串转换为Decimal型,，字符串为空、NULL、nbsp;时返回 0
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    public static decimal ToDecimal(this string text) {
        if (string.IsNullOrEmpty(text))
            return 0;
        if (text == "&nbsp;")
            return 0;

        return Convert.ToDecimal(text.Trim());
    }

    /// <summary>
    /// 字符串转换成DateTime类型
    /// </summary>
    /// <param name="text">字符串</param>
    /// <returns></returns>
    public static DateTime ToDateTime(this string text) {
        if ((string.IsNullOrEmpty(text)) || (text == "&nbsp;"))
            return DateTime.MinValue;

        return Convert.ToDateTime(text);
    }

    /// <summary>
    /// 将字符串转换成时间类型
    /// </summary>
    /// <param name="strDate"></param>
    /// <param name="formmat"></param>
    /// <returns></returns>
    public static DateTime ToDateTime(this string strDate, string formmat) {
        try {
            DateTime outDateTime;
            TryToDateTime(strDate, formmat, out outDateTime);
            return outDateTime;
        }
        catch {
            return DateTime.MinValue;
        }
    }

    /// <summary>
    /// 将字符串转换成时间类型
    /// </summary>
    /// <param name="strDate"></param>
    /// <param name="formmat"></param>
    /// <param name="outDateTime"></param>
    /// <returns></returns>
    public static bool TryToDateTime(this string strDate, string formmat, out DateTime outDateTime) {
        outDateTime = DateTime.MinValue;
        try {
            int year;
            int month;
            int day;
            int hour;
            int minute;
            int second;
            switch (formmat) {
                case "yyyyMMddHHmmss":
                    outDateTime = new DateTime(int.Parse(strDate.Substring(0, 4)),
                        int.Parse(strDate.Substring(4, 2)), int.Parse(strDate.Substring(6, 2)),
                        int.Parse(strDate.Substring(8, 2)), int.Parse(strDate.Substring(10, 2)),
                        int.Parse(strDate.Substring(12, 2)));
                    return true;
                case "yyMMddHHmmss":
                    year = int.Parse("20" + strDate.Substring(0, 2));
                    month = int.Parse(strDate.Substring(2, 2));
                    day = int.Parse(strDate.Substring(4, 2));
                    hour = int.Parse(strDate.Substring(6, 2));
                    minute = int.Parse(strDate.Substring(8, 2));
                    second = int.Parse(strDate.Substring(10, 2));
                    outDateTime = new DateTime(year, month, day, hour, minute, second);
                    return true;
                case "yyMMddHHmm":
                    year = int.Parse("20" + strDate.Substring(0, 2));
                    month = int.Parse(strDate.Substring(2, 2));
                    day = int.Parse(strDate.Substring(4, 2));
                    hour = int.Parse(strDate.Substring(6, 2));
                    minute = int.Parse(strDate.Substring(8, 2));
                    outDateTime = new DateTime(year, month, day, hour, minute, 0);
                    return true;
                case "yyMMdd":
                    outDateTime = new DateTime(int.Parse("20" + strDate.Substring(0, 2)),
                        int.Parse(strDate.Substring(2, 2)), int.Parse(strDate.Substring(4, 2)));
                    return true;
                case "yyyy-MM":
                    string[] strings = strDate.Split('-');
                    outDateTime = new DateTime(int.Parse(strings[0]), int.Parse(strings[1]), 1);
                    return true;
            }

            return true;
        }
        catch {
            return false;
        }
    }

    #endregion

    /// <summary>
    /// 判断一个字符串是否是16进制字符串，即应为 0-9 和 A-F（或 a-f）。
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static bool IsHexadecimal(this string input) {
        if (string.IsNullOrEmpty(input)) {
            return false; // 空字符串视为非法
        }

        // 正则表达式：匹配0-9、A-F、a-f组成的字符串
        // 允许包含空格
        string pattern = @"^[0-9A-Fa-f]+$";
        return Regex.IsMatch(input.Replace(" ", ""), pattern);
    }

    /// <summary>
    /// 将阿拉伯数字换成中文大写
    /// </summary>
    /// <param name="strRmb"></param>
    /// <returns></returns>
    public static string SingleNunberToChineseUpper(this string strRmb) {
        string outStr = strRmb;
        outStr = outStr.Replace("0", "零");
        outStr = outStr.Replace("1", "壹");
        outStr = outStr.Replace("2", "贰");
        outStr = outStr.Replace("3", "叁");
        outStr = outStr.Replace("4", "肆");
        outStr = outStr.Replace("5", "伍");
        outStr = outStr.Replace("6", "陆");
        outStr = outStr.Replace("7", "柒");
        outStr = outStr.Replace("8", "捌");
        outStr = outStr.Replace("9", "玖");
        return outStr;
    }

    /// <summary>
    /// 将中文大写换成阿拉伯数字
    /// </summary>
    /// <param name="cnString"></param>
    /// <returns></returns>
    private static decimal ChineseUpperToNunber(string cnString) {
        throw new NotImplementedException();
    }

    ///// <summary>
    ///// 16进制字符串转换为Byte
    ///// </summary>
    ///// <param name="hexString">16进制源字符串</param>
    ///// <returns>Byte类型数组</returns>
    //public static byte HexToByte(this string hexString) {
    //    string strTemp = hexString;
    //    int len = hexString.Length;
    //    if (len % 2 != 0)
    //        strTemp = "0" + hexString;

    //    return StrHelper.HexStringToByte(strTemp)[0];
    //}

    /// <summary>
    /// 16进制字符串转换为Byte
    /// </summary>
    /// <param name="jsonString">16进制源字符串</param>
    /// <param name="appendKey"></param>
    /// <param name="appendText"></param>
    /// <returns>Byte类型数组</returns>
    public static void JsonAppend(ref string jsonString, string appendKey, int appendText) {
        if (string.IsNullOrEmpty(jsonString)) {
            jsonString = "{}";
        }
        if (jsonString.EndsWith("}]")) {
            jsonString = jsonString.Remove(jsonString.Length - 2, 2);
            jsonString += ",";

            jsonString += "\"" + appendKey + "\":";
            jsonString += "\"" + appendText + "\"";
            jsonString += "}]";
        }
        else if (jsonString.EndsWith("}")) {
            jsonString = jsonString.Remove(jsonString.Length - 1, 1);
            if (jsonString != "{")
                jsonString += ",";

            jsonString += "\"" + appendKey + "\":";
            jsonString += appendText;
            jsonString += "}";
        }
        else {
            jsonString += "非正常JSon数据";
            return;
        }
    }

    /// <summary>
    /// 16进制字符串转换为Byte
    /// </summary>
    /// <param name="jsonString">16进制源字符串</param>
    /// <param name="appendKey"></param>
    /// <param name="appendText"></param>
    /// <returns>Byte类型数组</returns>
    public static void JsonAppend(ref string jsonString, string appendKey, string appendText) {
        if (string.IsNullOrEmpty(jsonString)) {
            jsonString = "{}";
        }
        if (jsonString.EndsWith("}]")) {
            jsonString = jsonString.Remove(jsonString.Length - 2, 2);
            jsonString += ",";

            jsonString += "\"" + appendKey + "\":";
            jsonString += "\"" + appendText + "\"";
            jsonString += "}]";
        }
        else if (jsonString.EndsWith("}")) {
            jsonString = jsonString.Remove(jsonString.Length - 1, 1);
            if (jsonString != "{")
                jsonString += ",";

            jsonString += "\"" + appendKey + "\":";
            jsonString += "\"" + appendText + "\"";
            jsonString += "}";
        }
        else {
            jsonString += "非正常JSon数据";
            return;
        }
    }

    /// <summary>
    /// 是否是一个合法的ip地址字符串
    /// </summary>
    /// <param name="ip"></param>
    /// <returns>是合法的返回ture，不是合法的返回false</returns>
    public static bool IsValidIPv4(this string ip) {
        var parts = ip.Split('.');
        if (parts.Length != 4) return false;
        foreach (var part in parts) {
            if (!int.TryParse(part, out int num) || num < 0 || num > 255)
                return false;
            if (part.Length > 1 && part.StartsWith("0"))
                return false; // 禁止前导零
        }
        return true;
    }




}